home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
201-225
/
disk_214
/
mandelvroom
/
src
/
recolor.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
26KB
|
870 lines
/*
* MandelVroom 2.0
*
* (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
*
* All rights reserved.
*
* Permission is hereby granted to distribute this program's source
* executable, and documentation for non-comercial purposes, so long as the
* copyright notices are not removed from the sources, executable or
* documentation. This program may not be distributed for a profit without
* the express written consent of the author Kevin L. Clague.
*
* This program is not in the public domain.
*
* Fred Fish is expressly granted permission to distribute this program's
* source and executable as part of the "Fred Fish freely redistributable
* Amiga software library."
*
* Permission is expressly granted for this program and it's source to be
* distributed as part of the Amicus Amiga software disks, and the
* First Amiga User Group's Hot Mix disks.
*
* contents: this file contains functions to redraw (or repaint) Mandelbrot
* and Julia projects. There are special high-performance functions to
* recolor 4 and 5 bit plane pictures (in assembly). There is also a
* function that can spawn off a child task to redraw the picture (for the
* other number of bit planes 1,2,3 and 6)
*/
#include "mandp.h"
extern LONG pSigMask;
/*
* ReColor a picture into a window
*/
ReColor( Pict )
register struct Picture *Pict;
{
/* This set of variables should not be rearranged or moved.
There is Assembly language used in this routine, to increase
performance. The assembly code depends on these variables
being located on Manx's stack. Obviously it is not too portable
or maintainable, but it is faster.
*/
SHORT *CountPtr;
UBYTE *ColorPtr;
register LONG CountX, CountY;
/* These variables are O.K. to rearrange and add to. */
register struct Window *Window;
register LONG dx,dy;
LONG i, Depth;
UBYTE *ColorSave;
LONG wx,wy,Sx;
if ( Pict == NULL )
return;
KillReColor( Pict );
FreeScrollTemp( Pict );
PauseChild(Pict);
Window = Pict->Window;
CountPtr = Pict->Counts;
CountX = Pict->CountX;
CountY = Pict->CountY;
Depth = screen->BitMap.Depth;
if (CountPtr == NULL || Pict->Flags & NO_RAM_GENERATE ) {
DispErrMsg("No counts to recolor",0);
return;
}
wx = CountX + Pict->LeftMarg + Pict->RightMarg;
wy = CountY + Pict->TopMarg + Pict->BotMarg;
dx = screen->Width - wx;
dy = screen->Height - wy;
if ( dx < 0 || dy < 0 ) {
DispErrMsg("Picture too big for screen.",0);
return;
}
dx -= Window->LeftEdge;
dy -= Window->TopEdge;
if ( dx < 0 || dy < 0 ) {
MoveWindow( Window, dx, dy );
}
dx = wx - Window->Width;
dy = wy - Window->Height;
if ( dx || dy ) {
SizeWindow(Window, dx, dy );
/* Spin till the window gets resized */
/* Gross eh? */
i = 0;
while (i++ < 10000 && Window->Width != wx && Window->Height != wy);
if (i == 10000) {
DispErrMsg("can't resize the window");
return;
}
BorderWindow(Window);
}
if (Pict->CurLine+Pict->TopMarg < Pict->Window->Height-Pict->BotMarg-1) {
SetAPen( Pict->Window->RPort, NORMALPEN );
RectFill( Pict->Window->RPort, Pict->LeftMarg,
Pict->CurLine + Pict->TopMarg,
Pict->Window->Width - Pict->RightMarg - 1,
Pict->Window->Height - Pict->BotMarg - 1);
}
Pict->Flags &= ~LENS_DISPLAYED;
MakeColorXlate( Pict );
if ( Depth != 4 && Depth != 5) {
ReColorSlow( Pict );
return;
}
/* try to get enough memory to recolor the picture fast. */
ColorPtr = ColorSave =
(UBYTE *) safeAllocMem( CountX * CountY + 1, 0L);
if (ColorPtr == (UBYTE *) NULL) {
ReColorSlow( Pict );
return;
}
WindowToFront(Window);
ClearMenuStrip(Window);
Delay(8);
LockLayers( BackWind->WLayer->LayerInfo );
/* We were able to allocate enough memory to translate the entire
picture from heights to pens. The array of pens is used to
quickly recolor the screen using Recolor4 or Recolor5 */
/* If you don't like the assembly, you can use this C instead */
#define SLOW1
#ifdef SLOW1
for (Sx = CountX*CountY; Sx-- >= 0; )
*(ColorPtr++) = *(Pict->ClrXlate + *(CountPtr++));
#else
#asm
CountPtr equ -4 ; these define where your variables
ColorBase equ -8 ; are located on Manx's stack
move.w d4,d1 ; this is ugly, but CountX is in d4
muls.w d5,d1 ; and CountY is in d5
sub.l #1,d1
move.l CountPtr(a5),a0
move.l _ColorXlate,a1
move.l ColorBase(a5),a6
ColorLoop
move.w (a0)+,d0
move.b (a1,d0.w),(a6)+
sub.l #1,d1
bge ColorLoop
#endasm
#endif
if (Depth == 4) {
ReColor4( ColorSave, Pict);
} else
if (Depth == 5) {
ReColor5( ColorSave, Pict);
}
UnlockLayers( BackWind->WLayer->LayerInfo );
AwakenChild(Pict);
SetMenuStrip(Window, Menu);
FreeMem(ColorSave,CountX*CountY+1);
} /* ReColor */
MakeColorXlate( Pict )
register struct Picture *Pict;
{
register LONG i,j;
/* So prepare the color translate table */
for (i = 0,j = 1023; i < NumContours; i++)
for (; j >= Pict->Heights[i] && j > 0; )
*(Pict->ClrXlate + j--) = Pict->Pens[i];
while (j >= 0) *(Pict->ClrXlate + j--) = 0;
}
/*
* Assembly code to recolor 4 bit planes
*/
ReColor4(ColorSave, Pict)
UBYTE *ColorSave;
register struct Picture *Pict;
{
/* This set of variables should not be rearranged or moved.
There is Assembly language used in this routine, to increase
performance. The assembly code depends on these variables
being located on Manx's stack. Obviously it is not too portable
or maintainable, but it is faster.
*/
SHORT Mask,Width;
LONG Mod,CMod;
SHORT LF,LP,RF,RP;
SHORT i,j,k,l;
LONG Sx,TL;
UBYTE *ColorPtr;
struct BitMap *BitMap;
/* This can be messed with */
SHORT CountX, CountY;
register struct Window *Window;
#asm
SaveReg reg a0-a6/d0-d7
Plane0 equ 8
Plane1 equ Plane0+4
Plane2 equ Plane0+8
Plane3 equ Plane0+12
Plane4 equ Plane0+16
Plane5 equ Plane0+20
CountX equ -50
CountY equ -48
BitMap equ -44
ColorPtr equ -40
TL equ -36
Sx equ -32
l equ -28
k equ -26
j equ -24
i equ -22
RP equ -20
RF equ -18
LP equ -16
LF equ -14
CMod equ -12
Mod equ -8
Width equ -4
Mask equ -2
ColorSave equ 8
#endasm
Window = Pict->Window;
BitMap = Window->RPort->BitMap;
CountX = Pict->CountX;
CountY = Pict->CurLine;
ColorPtr = ColorSave;
Sx = (screen->Width + 15) >> 4;
LP = Window->LeftEdge + Pict->LeftMarg;
LF = (LP + 15) & 0xfff0;
CMod = Pict->CountX - (LF-LP);
Mod = Sx - 1;
TL = Sx * (Window->TopEdge + Pict->TopMarg) + (LP-1 >> 4);
Width = LF-LP;
Mask = 0xffff << Width;
if ( Width > 0 ) {
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w CountY(a5),i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; for (i = CountY; i; i--) {
Y0Loop4 ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
B0Loop4
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
sub.w d1,d7 ; same for bit plane 5
bgt B0Loop4 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y0Loop4
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
;
}
RP = LP + Pict->CountX & 0xfff0;
RF = RP - 16;
CMod = Pict->CountX - (RP-LF);
Mod = Sx - ((RP-LF) >> 4);
TL++;
Width = (RP-LF) >> 4;
ColorPtr = ColorSave + LF - LP;
if (Width > 0 ) {
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w CountY(a5),i(a1) ;i = CountY;
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; for (i = CountY; i; i--) {
YLoop4 ; /* for each column */
move.w Width(a1),j(a1) ; for (j = Width; j; j--) {
XLoop4 ; /* pack a word for each bit plane */
move.w #16,d7 ; for (k = 16; k; k--) {
BLoop4
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
sub.w d1,d7 ; same for bit plane 5
bgt BLoop4 ; } /* did each bit in bit plane word */
move.w d2,(a2)+ ; Save the packed data in bit planes
move.w d3,(a3)+
move.w d4,(a4)+
move.w d5,(a5)+
sub.w d1,j(a1) ; } /* did each word in a row */
tst.w j(a1)
bgt XLoop4
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt YLoop4
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
;
}
TL += Width;
Width = LP + Pict->CountX - RP;
CMod = Pict->CountX - Width;
Mod = Sx - 1;
Mask = 0xffff >> Width;
ColorPtr = ColorSave + RP - LP;
if ( Width > 0 ) {
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w CountY(a5),i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
Y2Loop4 ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
B2Loop4
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
sub.w d1,d7 ; same for bit plane 5
bgt B2Loop4 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
move.w #16,d0
sub.w Width(a1),d0
asl.w d0,d2
asl.w d0,d3
asl.w d0,d4
asl.w d0,d5
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y2Loop4
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
;
}
} /* ReColor 4 bit planes */
/*
* Assembly code to recolor 5 bit planes
*/
ReColor5(ColorSave, Pict)
UBYTE *ColorSave;
register struct Picture *Pict;
{
/* This set of variables should not be rearranged or moved.
There is Assembly language used in this routine, to increase
performance. The assembly code depends on these variables
being located on Manx's stack. Obviously it is not too portable
or maintainable, but it is faster.
*/
SHORT Mask,Width;
LONG Mod,CMod;
SHORT LF,LP,RF,RP;
SHORT i,j,k,l;
LONG Sx,TL;
UBYTE *ColorPtr;
struct BitMap *BitMap;
/* These can be messed with */
SHORT CountX, CountY;
register struct Window *Window;
Window = Pict->Window;
BitMap = Window->RPort->BitMap;
CountX = Pict->CountX;
CountY = Pict->CurLine;
ColorPtr = ColorSave;
Sx = (screen->Width + 15) >> 4;
LP = Window->LeftEdge + Pict->LeftMarg;
LF = (LP + 15) & 0xfff0;
CMod = CountX - (LF-LP);
Mod = Sx - 1;
TL = Sx * (Window->TopEdge + Pict->TopMarg) + (LP-1 >> 4);
Width = LF-LP;
Mask = 0xffff << Width;
if ( Width > 0 ) {
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w CountY(a5),i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l Plane4(a0),a6 ;Same for fifth bit plane.
adda.l d0,a6
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
Y0Loop5 ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
eor.w d6,d6
B0Loop5
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
asr.b d1,d0 ; same for bit plane 4
addx.w d6,d6
sub.w d1,d7 ; same for bit plane 5
bgt B0Loop5 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
and.w d0,(a6)
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
or.w d6,(a6)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
add.l d0,a6
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y0Loop5
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
;
}
RP = LP + CountX & 0xfff0;
RF = RP - 16;
CMod = CountX - (RP-LF);
Mod = Sx - ((RP-LF) >> 4);
TL++;
Width = (RP-LF) >> 4;
ColorPtr = ColorSave + LF - LP;
if ( Width > 0 ) {
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w CountY(a5),i(a1) ;i = CountY;
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l Plane4(a0),a6 ;Same for fifth bit plane.
adda.l d0,a6
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
YLoop5 ; /* for each column */
move.w Width(a1),j(a1) ; for (j = Width; j; j--) {
XLoop5 ; /* pack a word for each bit plane */
move.w #16,d7 ; for (k = 16; k; k--) {
BLoop5
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
asr.b d1,d0 ; same for bit plane 4
addx.w d6,d6
sub.w d1,d7 ; same for bit plane 5
bgt BLoop5 ; } /* did each bit in bit plane word */
move.w d2,(a2)+ ; Save the packed data in bit planes
move.w d3,(a3)+
move.w d4,(a4)+
move.w d5,(a5)+
move.w d6,(a6)+
sub.w d1,j(a1) ; } /* did each word in a row */
tst.w j(a1)
bgt XLoop5
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
add.l d0,a6
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt YLoop5
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
;
}
TL += Width;
Width = LP + CountX - RP;
CMod = CountX - Width;
Mod = Sx - 1;
Mask = 0xffff >> Width;
ColorPtr = ColorSave + RP - LP;
if ( Width > 0 ) {
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w CountY(a5),i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l Plane4(a0),a6 ;Same for fifth bit plane.
adda.l d0,a6
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
Y2Loop5 ; ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
eor.w d6,d6
B2Loop5
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
asr.b d1,d0 ; same for bit plane 4
addx.w d6,d6
sub.w d1,d7 ; same for bit plane 5
bgt B2Loop5 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
and.w d0,(a6)
move.w #16,d0
sub.w Width(a1),d0
asl.w d0,d2
asl.w d0,d3
asl.w d0,d4
asl.w d0,d5
asl.w d0,d6
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
or.w d6,(a6)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
add.l d0,a6
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y2Loop5
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
;
}
} /* ReColor 5 bit planes */
static struct Picture *ReColorPict;
ReColorSlow( Pict )
register struct Picture *Pict;
{
int ReColorTask();
WindowToFront(Pict->Window);
Pict->ColorState = GENERATESTATE;
ReColorPict = Pict;
Pict->cTask = CreateTask( "ReColor", 0, ReColorTask, 1024);
if ( Pict->cTask == NULL ) {
DispErrMsg("Could not create recolor task",0);
}
/* Do this so we are sure child is done with ReColorPict */
Wait( pSigMask );
}
ReColorTask( )
{
register struct Picture *Pict;
register struct RastPort *Rp;
register UBYTE OldColor, NewColor;
register LONG x, y;
LONG xl, yl;
SHORT *CountPtr;
struct Window *Window;
geta4();
Pict = ReColorPict;
/* Signal Parent that we have accessed ReColorPict */
Signal( mTask, pSigMask );
Window = Pict->Window;
Pict->ColorChildState = RECOLORINCOMPLETE;
Rp = Window->RPort;
CountPtr = Pict->Counts;
OldColor = 0xff;
xl = Pict->CountX + Pict->LeftMarg;
yl = Pict->CurLine + Pict->TopMarg;
for (y = Pict->TopMarg; y < yl; y++) {
ObtainSemaphore( &Pict->WindowSemi );
OldColor = *(Pict->ClrXlate + *CountPtr);
Move( Rp, Pict->LeftMarg, y);
for (x = Pict->LeftMarg; x < xl; x++) {
NewColor = *(Pict->ClrXlate + *CountPtr++);
if ( NewColor != OldColor) {
SetAPen( Rp, OldColor );
if ( x < Window->Width - Window->BorderRight) {
Draw( Rp, x, y);
}
OldColor = NewColor;
}
}
SetAPen( Rp, NewColor );
Draw( Rp, x-1, y);
ReleaseSemaphore( &Pict->WindowSemi );
ReColorPause( Pict );
}
Pict->ColorChildState = RECOLORCOMPLETE;
/* Indicate that generation has finished for this task */
Signal( mTask, mSigMask ); /* signal parent as to change */
while (Pict->ColorState != PAUSESTATE) ;
ReColorPause(Pict); /* signal back so parent doesn't hang */
} /* ReColorTask */
KillReColor( Pict )
register struct Picture *Pict;
{
register struct Task *cTask;
if ( cTask = Pict->cTask ) {
PauseReColor( Pict );
DeleteTask( cTask );
Pict->cTask = NULL;
}
}